import java.io.File;
import java.util.ArrayList;
import java.util.List;

public class VideoTool
{

	public static void main(String[] argv) throws Exception
	{
		//Example：
		//-info        "D:\BaiduNetdiskDownload\源" "D:\BaiduNetdiskDownload\result.csv" 
		//-cut         "D:\BaiduNetdiskDownload\源" "D:\BaiduNetdiskDownload\剪切" 15 4
		//-delog       "D:\BaiduNetdiskDownload\剪切" "D:\BaiduNetdiskDownload\去水印" 1057 8 214 52
		//-addlog      "D:\BaiduNetdiskDownload\剪切" "D:\BaiduNetdiskDownload\去水印" "水印路径" 1057 8
		//-replacelog  "D:\BaiduNetdiskDownload\剪切" "D:\BaiduNetdiskDownload\替换水印" "水印路径" 1057 8 214 52
		//-rename      "D:\BaiduNetdiskDownload\源" "老字符串" "新字符串" 
		new VideoTool().parseCmd(argv);
	}
	
	/**
	 * 命令行解析
	 * -i --info    src dest           导出视频信息   
	 * -c --cut     src dest head tail 掐头去尾       
	 * -d --delogo  src dest x y w h   去logo
	 * @param argv
	 * @throws Exception 
	 */
	public void parseCmd(String[] argv) throws Exception
	{
		if(argv.length < 3)
		{
			System.out.println("Error parameters");
			return;
		}
		
		if(argv[0].equalsIgnoreCase("-info"))
		{
			String src = argv[1];
			String dest = argv[2];
			exportVideoInfo(src, dest);
		}
		else if(argv[0].equalsIgnoreCase("-cut"))
		{
			String src = argv[1];
			String dest = argv[2];
			String head = argv[3];
			String tail = argv[4];
			cutVideo(src, dest, Float.parseFloat(head), Float.parseFloat(tail));
		}
		else if(argv[0].equalsIgnoreCase("-delogo"))
		{
			String src = argv[1];
			String dest = argv[2];
			String x = argv[3];
			String y = argv[4];
			String w = argv[5];
			String h = argv[6];
			delogo(src, dest, 
							Integer.parseInt(x),
							Integer.parseInt(y),
							Integer.parseInt(w),
							Integer.parseInt(h));
		}
		else if(argv[0].equalsIgnoreCase("-addlogo"))
		{
			String src = argv[1];
			String dest = argv[2];
			String logo = argv[3];
			String x = argv[4];
			String y = argv[5];
			addLogo(src, dest, logo, Integer.parseInt(x), Integer.parseInt(y));
		}
		else if(argv[0].equalsIgnoreCase("-replacelogo"))
		{
			String src = argv[1];
			String dest = argv[2];
			String logo = argv[3];
			String x = argv[4];
			String y = argv[5];
			String w = argv[6];
			String h = argv[7];
			replaceLogo(src, dest, logo, Integer.parseInt(x), Integer.parseInt(y), Integer.parseInt(w), Integer.parseInt(h));
		}
		else if(argv[0].equalsIgnoreCase("-rename"))
		{
			String src = argv[1];
			String oldstr = argv[2];
			String newstr = argv[3];
			renameFile(src, oldstr, newstr);
		}
		else
		{
			System.out.println("Unknown parameter: " + argv[0]);
		}
	}

	/**
	 * 递归获取指定目录下所有的视频音频的信息，并输出到指定文件中
	 * 
	 * @param srcDir   源目录
	 * @param destFile 输出文件
	 * @throws Exception
	 */
	public void exportVideoInfo(String srcDir, String destFile) throws Exception
	{
		// 查找所有文件
		List<File> fileList = new ArrayList<File>();
		Utils.getFile(srcDir, fileList);
		System.out.println("Total: " + fileList.size());

		// 获取每个视频文件的信息
		List<String> infoList = new ArrayList<String>();
		infoList.add(VideoInfo.getCsvTitle());
		for (File f : fileList)
		{
			VideoInfo vi = VideoUtils.getVideoInfo(f);
			if (vi == null)
			{
				continue;
			}
			
			infoList.add(vi.toCsv());
			System.out.println("Get file: " + vi.fullpath);
		}

		// 把结果写入文件
		Utils.writeFile(destFile, infoList);
	}

	/**
	 * 批量掐头去尾切割视频，开头去掉cutHead秒，结尾去掉cutTail秒
	 * @param srcDir  视频源目录
	 * @param destDir 输出目录
	 * @param cutHead 开头要去掉的秒数
	 * @param cutTail 结尾要去掉的秒数
	 * @throws Exception 
	 */
	public void cutVideo(String srcDir, String destDir, float cutHead, float cutTail) throws Exception
	{
		// 查找所有文件
		List<File> fileList = new ArrayList<File>();
		Utils.getFile(srcDir, fileList);
		System.out.println("Total: " + fileList.size());

		// 获取每个视频文件的信息
		List<String> infoList = new ArrayList<String>();
		infoList.add(VideoInfo.getCsvTitle());
		for (File f : fileList)
		{
			VideoInfo vi = VideoUtils.getVideoInfo(f);
			if (vi == null)
			{
				continue;
			}
			
			//总时长
			float totalDuration = VideoUtils.parseTimeToSecond(vi.duration);
			
			String src = f.getAbsolutePath();
			String dest = src.replace(srcDir, destDir);
			
			File destParentPath = new File(new File(dest).getParent());
			if(!destParentPath.exists())
			{
				destParentPath.mkdirs();
			}
			float start = cutHead + 1;
			float duration = totalDuration - cutHead - cutTail;
			duration = (duration <= 0 ? 0 : duration);
			
			//开始切割
			VideoUtils.cutVideo(src, dest, start, duration);

			infoList.add(vi.toCsv());
		}

	}

	/**
	 * 通过周围像素插值去除 logo
	 * @param srcDir  原目录
	 * @param destDir 目标目录
	 * @param x       logo所在的位置（左上角x坐标，像素）
	 * @param y       logo所在的位置（左上角y坐标，像素）
	 * @param w       logo的宽度
	 * @param h       logo的高度
	 */
	public void delogo(String srcDir, String destDir, int x, int y, int w, int h) throws Exception
	{
		// 查找所有文件
		List<File> fileList = new ArrayList<File>();
		Utils.getFile(srcDir, fileList);
		System.out.println("Total: " + fileList.size());

		for (File f : fileList)
		{
			String src = f.getAbsolutePath();
			String dest = src.replace(srcDir, destDir);
			
			File destParentPath = new File(new File(dest).getParent());
			if(!destParentPath.exists())
			{
				destParentPath.mkdirs();
			}
			
			//去水印
			VideoUtils.delogo(src, dest, x, y, w, h);
		}

	}
	
	/**
	 * 视频加水印
	 * @param srcDir   原目录
	 * @param destDir  目标目录
	 * @param logopath 水印的路径
	 * @param x        logo所在的位置（左上角x坐标，像素）
	 * @param y        logo所在的位置（左上角y坐标，像素）
	 */
	public void addLogo(String srcDir, String destDir, String logopath, int x, int y) throws Exception
	{
		List<File> fileList = new ArrayList<File>();
		Utils.getFile(srcDir, fileList);
		System.out.println("Total: " + fileList.size());

		for (File f : fileList)
		{
			String src = f.getAbsolutePath();
			String dest = src.replace(srcDir, destDir);
			
			File destParentPath = new File(new File(dest).getParent());
			if(!destParentPath.exists())
			{
				destParentPath.mkdirs();
			}
			
			//加水印
			VideoUtils.addlogo(src, dest, logopath, x, y);
		}
	}
	
	/**
	 * 替换水印
	 * @param srcDir   原目录
	 * @param destDir  目标目录
	 * @param logopath 水印的路径
	 * @param x        logo所在的位置（左上角x坐标，像素）
	 * @param y        logo所在的位置（左上角y坐标，像素）
	 * @param w        原始logo的宽度
	 * @param h        原始logo的高度
	 */
	public void replaceLogo(String srcDir, String destDir, String logopath, int x, int y, int w, int h) throws Exception
	{
		List<File> fileList = new ArrayList<File>();
		Utils.getFile(srcDir, fileList);
		System.out.println("Total: " + fileList.size());

		for (File f : fileList)
		{
			String src = f.getAbsolutePath();
			String dest = src.replace(srcDir, destDir);
			
			File destParentPath = new File(new File(dest).getParent());
			if(!destParentPath.exists())
			{
				destParentPath.mkdirs();
			}
			
			//替换水印
			VideoUtils.replaceLogo(src, dest, logopath, x, y, w, h);
		}
	}
	
	/**
	 * 批量修改文件名
	 * @param srcDir 源目录
	 * @param oldStr 要替换的字符串
	 * @param newStr 新的字符串
	 */
	public void renameFile(String srcDir, String oldStr, String newStr)
	{
		List<File> fileList = new ArrayList<File>();
		Utils.getFile(srcDir, fileList);
		System.out.println("Total: " + fileList.size());

		for (File f : fileList)
		{
			String fullpath = f.getAbsolutePath();
			String parentDir = f.getParent();
			String filename = f.getName();
			
			String newfullpath = parentDir + "/" + filename.replace(oldStr, newStr);
			f.renameTo(new File(newfullpath));
			
			System.out.println(fullpath + " => " + newfullpath);
		}
	}
	
}